import ttkbootstrap as ttk
from ttkbootstrap.scrolled import ScrolledText
from tkinter import messagebox
import threading
from engine.search_engine import SearchEngine
import os
import time
import webbrowser

class SearchApp:
    def __init__(self, root):
        self.root = root
        self.root.title("知识点查询工具")
        self.root.geometry("900x700")
        self.root.minsize(800, 600)
        
        # 存储链接映射
        self.link_map = {}
        
        # 创建界面
        self.create_widgets()
        
    def create_widgets(self):
        # 主容器
        main_container = ttk.Frame(self.root)
        main_container.pack(fill=ttk.BOTH, expand=True, padx=10, pady=10)
        
        # # 标题
        # title_label = ttk.Label(
        #     main_container, 
        #     text="知识点查询工具", 
        #     font=("Arial", 18, "bold"),
        #     bootstyle="primary"
        # )
        # title_label.pack(pady=(0, 20))
        
        # 搜索引擎选择框架
        engine_frame = ttk.LabelFrame(main_container, text="选择搜索引擎", padding=10, bootstyle="primary")
        engine_frame.pack(fill=ttk.X, pady=(0, 10))
        
        self.engine_var = ttk.StringVar(value="baidu")
        baidu_radio = ttk.Radiobutton(
            engine_frame, 
            text="百度", 
            variable=self.engine_var, 
            value="baidu",
            bootstyle="primary"
        )
        google_radio = ttk.Radiobutton(
            engine_frame, 
            text="谷歌", 
            variable=self.engine_var, 
            value="google",
            bootstyle="primary"
        )
        
        baidu_radio.pack(side=ttk.LEFT, padx=(0, 20))
        google_radio.pack(side=ttk.LEFT)
        
        # 搜索输入框架
        search_frame = ttk.LabelFrame(main_container, text="查询内容", padding=10, bootstyle="primary")
        search_frame.pack(fill=ttk.X, pady=(0, 10))
        
        # 搜索输入和按钮
        input_frame = ttk.Frame(search_frame)
        input_frame.pack(fill=ttk.X)
        
        self.search_entry = ttk.Entry(input_frame, font=("Arial", 12))
        self.search_entry.pack(side=ttk.LEFT, fill=ttk.X, expand=True, ipady=5)
        
        self.search_button = ttk.Button(
            input_frame, 
            text="查询", 
            command=self.start_search,
            bootstyle="primary"
        )
        self.search_button.pack(side=ttk.RIGHT, padx=(10, 0), ipadx=20, ipady=5)
        
        # 绑定回车键搜索
        self.search_entry.bind('<Return>', lambda event: self.start_search())
        
        # 结果显示框架
        result_frame = ttk.LabelFrame(main_container, text="查询结果", padding=10, bootstyle="primary")
        result_frame.pack(fill=ttk.BOTH, expand=True)
        
        # 创建滚动文本框
        self.result_text = ScrolledText(
            result_frame,
            wrap=ttk.WORD,
            font=("Arial", 10),
            height=15
        )
        self.result_text.pack(fill=ttk.BOTH, expand=True, pady=5)
        
        # 设置文本框标签样式
        text_widget = self.result_text.text
        text_widget.tag_configure("title", font=("Arial", 16, "bold"), spacing3=15, foreground="#0055aa")
        text_widget.tag_configure("subtitle", font=("Arial", 13, "bold"), lmargin1=10, lmargin2=10, spacing1=8, spacing3=5)
        text_widget.tag_configure("link", foreground="#0066cc", underline=True, font=("Arial", 10, "italic"))
        text_widget.tag_configure("abstract", lmargin1=25, lmargin2=25, spacing1=3, spacing3=10, font=("Arial", 10))
        text_widget.tag_configure("separator", spacing3=15)
        text_widget.tag_configure("info", foreground="#555555", font=("Arial", 10, "italic"), lmargin1=10, lmargin2=10)
        text_widget.tag_configure("result_count", font=("Arial", 12, "bold"), foreground="#007700", lmargin1=10, lmargin2=10)
        text_widget.tag_configure("no_result", font=("Arial", 11), foreground="#aa0000", lmargin1=10, lmargin2=10)
        text_widget.tag_configure("content_title", font=("Arial", 11, "bold"), foreground="#000000", lmargin1=25, lmargin2=25, spacing1=8)
        text_widget.tag_configure("content", lmargin1=35, lmargin2=35, spacing1=3, spacing3=10, font=("Arial", 10))
        # 添加新的标签样式以提高可读性
        text_widget.tag_configure("result_item", background="#f8f9fa", relief="ridge", borderwidth=1, lmargin1=15, lmargin2=15, rmargin=10)
        text_widget.tag_configure("result_header", font=("Arial", 12, "bold"), foreground="#2c3e50", justify="left")
        text_widget.tag_configure("result_link", foreground="#3498db", underline=True, font=("Arial", 9), justify="left")
        text_widget.tag_configure("result_abstract", lmargin1=30, lmargin2=30, spacing1=3, spacing3=5, font=("Arial", 10), justify="left")
        text_widget.tag_configure("result_content", lmargin1=30, lmargin2=30, spacing1=3, spacing3=8, font=("Arial", 9))
        text_widget.tag_configure("section_separator", background="#ecf0f1", spacing1=5, spacing3=10)
        
        # 状态栏
        self.status_var = ttk.StringVar(value="就绪 - 请输入要查询的知识点")
        self.status_bar = ttk.Label(
            main_container, 
            textvariable=self.status_var, 
            bootstyle="secondary",
            padding=(10, 5)
        )
        self.status_bar.pack(side=ttk.BOTTOM, fill=ttk.X, pady=(10, 0))
        
        # 初始化显示提示信息
        self.show_initial_message()
        
    def show_initial_message(self):
        text_widget = self.result_text.text
        text_widget.delete(1.0, ttk.END)
        text_widget.insert(ttk.END, "知识点查询说明\n", "title")
        text_widget.insert(ttk.END, "\n本工具将查询您输入的知识点，并将结果保存为Markdown格式：\n", "abstract")
        text_widget.insert(ttk.END, "• 支持百度和谷歌搜索引擎\n", "abstract")
        text_widget.insert(ttk.END, "• 查询结果将保存在results文件夹中\n", "abstract")
        text_widget.insert(ttk.END, "• 文件名为: 搜索引擎_查询内容.md\n", "abstract")
        text_widget.insert(ttk.END, "• 查询结果包含标题、链接和摘要信息\n", "abstract")
        text_widget.insert(ttk.END, "• 点击链接可在浏览器中打开页面\n", "abstract")
        
    def start_search(self):
        # 在单独线程中执行搜索，避免界面冻结
        search_thread = threading.Thread(target=self.perform_search)
        search_thread.daemon = True
        search_thread.start()
        
    def perform_search(self):
        query = self.search_entry.get().strip()
        if not query:
            self.status_var.set("请输入要查询的内容")
            return
            
        engine_type = self.engine_var.get()
        self.status_var.set(f"正在使用{engine_type}查询: {query}")
        self.search_button.config(state=ttk.DISABLED)
        
        try:
            # 执行搜索
            engine = SearchEngine(engine_type)
            results = engine.search(query, 6)  # 获取前6个结果
            
            # 显示结果
            self.display_results(query, results, engine_type)
            
            # 保存为markdown文件
            self.save_results(query, results, engine_type)
            
            if results:
                self.status_var.set(f"查询完成，找到{len(results)}个结果，已保存到results文件夹")
            else:
                # 即使没有找到结果，也给出更积极的提示
                self.status_var.set("查询完成，搜索结果已保存到results文件夹（无相关结果）")
        except Exception as e:
            self.status_var.set(f"查询出错: {str(e)}")
            messagebox.showerror("错误", f"查询过程中出现错误:\n{str(e)}")
        finally:
            self.search_button.config(state=ttk.NORMAL)
            
    def display_results(self, query, results, engine_type):
        # 清空之前的结果和链接映射
        self.link_map.clear()
        text_widget = self.result_text.text
        text_widget.delete(1.0, ttk.END)
        
        # 显示搜索结果
        engine_name = "百度" if engine_type == "baidu" else "谷歌"
        text_widget.insert(ttk.END, f"{engine_name}查询结果\n", "title")
        text_widget.insert(ttk.END, f"查询内容: {query}\n", "subtitle")
        
        if not results:
            text_widget.insert(ttk.END, "\n未找到相关结果\n", "no_result")
            text_widget.insert(ttk.END, "但这可能是正常的，具体取决于查询内容和搜索引擎。\n\n", "info")
            text_widget.insert(ttk.END, "可能的原因：\n", "abstract")
            text_widget.insert(ttk.END, "• 查询内容较为特殊或不常见\n", "abstract")
            text_widget.insert(ttk.END, "• 搜索引擎限制了爬虫访问\n", "abstract")
            text_widget.insert(ttk.END, "• 网络连接问题\n", "abstract")
            text_widget.insert(ttk.END, "• 搜索引擎反爬虫机制\n", "abstract")
            return
            
        text_widget.insert(ttk.END, f"\n找到 {len(results)} 个相关结果:\n", "result_count")
        text_widget.insert(ttk.END, "="*60 + "\n", "section_separator")
        
        for i, result in enumerate(results, 1):
            # 添加结果项背景
            start_pos = text_widget.index(ttk.END+"-1c")
            
            # 添加标题
            text_widget.insert(ttk.END, f"\n{i}. {result['title']}\n", "result_header")
            
            # 添加可点击的链接
            link_tag = f"link_{i}"
            self.link_map[link_tag] = result['url']
            text_widget.insert(ttk.END, f"🔗 链接: {result['url']}\n", link_tag)
            text_widget.tag_bind(link_tag, "<Button-1>", lambda e, tag=link_tag: self.open_link(tag))
            text_widget.tag_bind(link_tag, "<Enter>", lambda e, w=text_widget, tag=link_tag: w.config(cursor="hand2"))
            text_widget.tag_bind(link_tag, "<Leave>", lambda e, w=text_widget: w.config(cursor=""))
            
            # 添加摘要
            text_widget.insert(ttk.END, f"\n📝 摘要:\n", "result_abstract")
            text_widget.insert(ttk.END, f"{result['abstract']}\n", "result_abstract")
            
            # 添加提取的内容
            text_widget.insert(ttk.END, f"\n📄 页面内容:\n", "content_title")
            text_widget.insert(ttk.END, f"{result['content']}\n", "result_content")
            
            # 结束背景标记
            end_pos = text_widget.index(ttk.END+"-1c")
            text_widget.tag_add("result_item", start_pos, end_pos)
            
            # 添加分隔线
            text_widget.insert(ttk.END, "\n" + "-"*50 + "\n", "section_separator")
            
    def open_link(self, link_tag):
        """在浏览器中打开链接"""
        url = self.link_map.get(link_tag)
        if url:
            try:
                webbrowser.open(url)
                self.status_var.set(f"正在打开链接: {url}")
            except Exception as e:
                self.status_var.set(f"打开链接失败: {str(e)}")
                messagebox.showerror("错误", f"无法打开链接:\n{str(e)}")
            
    def save_results(self, query, results, engine_type):
        # 确保results目录存在（在information_get项目目录下）
        results_dir = "information_get/results"
        os.makedirs(results_dir, exist_ok=True)
        
        # 创建文件名
        safe_query = "".join(c for c in query if c.isalnum() or c in (' ', '-', '_')).rstrip()
        filename = f"{results_dir}/{engine_type}_{safe_query}.md"
        
        # 检查文件是否已存在
        if os.path.exists(filename):
            # 如果文件已存在，读取现有内容
            with open(filename, "r", encoding="utf-8") as f:
                existing_content = f.read()
        else:
            # 如果文件不存在，创建初始内容
            engine_name = "百度" if engine_type == "baidu" else "谷歌"
            existing_content = f"# {engine_name}查询结果\n\n**查询内容**: {query}\n\n"
        
        # 准备新增内容
        new_content = f"\n## 新查询结果 - {time.strftime('%Y-%m-%d %H:%M:%S')}\n\n"
        
        if not results:
            new_content += "未找到相关结果，但这可能是正常的，具体取决于查询内容和搜索引擎。\n\n"
            new_content += "可能的原因：\n"
            new_content += "- 查询内容较为特殊或不常见\n"
            new_content += "- 搜索引擎限制了爬虫访问\n"
            new_content += "- 网络连接问题\n"
            new_content += "- 搜索引擎反爬虫机制\n"
        else:
            for i, result in enumerate(results, 1):
                new_content += f"## {len(results) - i + 1}. {result['title']}\n\n"
                new_content += f"- **链接**: [{result['url']}]({result['url']})\n\n"
                new_content += f"- **摘要**: {result['abstract']}\n\n"
                new_content += f"- **页面内容**:\n\n{result['content']}\n\n"
                new_content += "---\n\n"
        
        # 将新增内容追加到现有内容
        updated_content = existing_content + new_content
        
        # 写入更新后的内容到文件
        with open(filename, "w", encoding="utf-8") as f:
            f.write(updated_content)
                
        self.status_var.set(f"结果已保存到: {filename}")
